﻿using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using PropertyChanged;
using RandomMobileNumber.Models;
using RandomMobileNumber.Views;
using System;
using System.Linq;
using System.Collections.ObjectModel;
using System.Threading;
using System.Windows;

namespace RandomMobileNumber.ViewModels
{
    [ImplementPropertyChanged]
    public class MainViewModel : ViewModelBase
    {
        public ObservableCollection<Number> NumberList { get; set; }
        public ObservableCollection<Number> SelectedNumbers { get; set; }
        public Number CurrentNumber { get; set; }
        /// <summary>
        /// 用户已选号码
        /// </summary>
        public Number CurrentUserSelectedNumber { get; set; }
        public int CurrentIndex { get; set; }
        public string Title { get; set; }
        public bool Canceled { get; set; }
        private static readonly Random random = new Random();

        private Timer RandomTimer;

        private static readonly object syncLock = new object();

        public MainViewModel()
        {
            this.Title = "随机选号";

            LoadNumbers();
            SelectedNumbers = new ObservableCollection<Number>();
            Canceled = true;

            AppService.CreateShortcut(Title);
        }

        private void LoadNumbers()
        {
            bool imported = AppService.ImportExcelToDatabase();

            if (!imported)
            {
                Messenger.Default.Send<NotificationMessage>(new NotificationMessage("未能将Excel数据导入到数据库，请联系开发人员"));
                App.Current.Shutdown(100);
            }

            var numbers = from n in AppService.GetNumbers()
                          where n.sold.Equals(0) && n.reserved.Equals(0)
                          select n;
            NumberList = new ObservableCollection<Number>(numbers);
        }

        static int _getRandomNumber(int min, int max)
        {
            lock (syncLock)
                return random.Next(min, max);
        }

        private void _timerCallBack(object state)
        {
            if (Canceled)
            {
                RandomTimer.Dispose();

                App.Current.Dispatcher.Invoke(() =>
                {
                    _setNumber();
                });
            }
            else
            {
                CurrentIndex = _getRandomNumber(0, NumberList.Count);
                CurrentNumber = NumberList[CurrentIndex];
            }
        }

        private void _setNumber()
        {
            lock (syncLock)
            {
                SelectedNumbers.Add(CurrentNumber);
                NumberList.RemoveAt(CurrentIndex);
            }
        }

        private RelayCommand randomNumberCommand;

        /// <summary>
        /// 回车摇号/停止摇号
        /// </summary>
        public RelayCommand RandomNumberCommand
        {
            get
            {
                return randomNumberCommand ?? (randomNumberCommand = new RelayCommand(() =>
                {
                    if (Canceled)
                        RandomTimer = new Timer(_timerCallBack, null, 300, 30);

                    Canceled = !Canceled;

                    Title = Canceled ? "准备摇号" : "正在摇号";
                }));
            }
        }

        private RelayCommand setUserSelectedNumberCommand;

        /// <summary>
        /// 已选号码双击
        /// </summary>
        public RelayCommand SetUserSelectedNumberCommand
        {
            get
            {
                return setUserSelectedNumberCommand ?? (setUserSelectedNumberCommand = new RelayCommand(() =>
                {
                    NumberPropertyWindow editWin = new NumberPropertyWindow();
                    var model = editWin.DataContext as NumberPropertyViewModel;

                    model.Number = CurrentUserSelectedNumber == null ? CurrentNumber : CurrentUserSelectedNumber;

                    if (model.Number == null)
                    {
                        MessengerInstance.Send(new NotificationMessage("请选择号码"));
                        return;
                    }

                    var result = (bool)editWin.ShowDialog();

                    if (result)
                    {
                        if (model.Number.sold.Equals(1))
                            model.Number.soldDate = DateTime.Now;

                        bool updateResult = App.SqlClient.Update<Number>(model.Number);
                        if (updateResult)
                        {
                            LoadNumbers();
                            MessengerInstance.Send(new NotificationMessage("保存成功"));
                        }

                    }
                }));
            }
        }

        private RelayCommand viewSoldNumberCommand;

        /// <summary>
        /// 查看已售号码
        /// </summary>
        public RelayCommand ViewSoldNumberCommand
        {
            get
            {
                return viewSoldNumberCommand ?? (viewSoldNumberCommand = new RelayCommand(() =>
                {
                    SoldWindow win = new SoldWindow();
                    var model = win.DataContext as SoldViewModel;

                    var result = (bool)win.ShowDialog();

                    if (result)
                    {

                    }
                }));
            }
        }

        private RelayCommand viewReservedNumberCommand;

        /// <summary>
        /// 查看预留号码
        /// </summary>
        public RelayCommand ViewReservedNumberCommand
        {
            get
            {
                return viewReservedNumberCommand ?? (viewReservedNumberCommand = new RelayCommand(() =>
                {
                    RservedWindow win = new RservedWindow();
                    var model = win.DataContext as ReservedViewModel;

                    var result = (bool)win.ShowDialog();

                    if (result)
                    {

                    }
                }));
            }
        }

        private RelayCommand helpCommand;


        /// <summary>
        /// 查看预留号码
        /// </summary>
        public RelayCommand HelpCommand
        {
            get
            {
                return helpCommand ?? (helpCommand = new RelayCommand(() =>
                {
                    var base_dir = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
                    System.Diagnostics.Process.Start(base_dir + "\\res\\help.txt");
                }));
            }
        }

        private RelayCommand refreshCommand;


        /// <summary>
        /// 查看预留号码
        /// </summary>
        public RelayCommand RefreshCommand
        {
            get
            {
                return refreshCommand ?? (refreshCommand = new RelayCommand(() =>
                {
                    if (SelectedNumbers.Count > 0)
                    {
                        var result = MessageBox.Show("确定要刷新页面？所有已选号码将被清空", "确认命令", MessageBoxButton.OKCancel, MessageBoxImage.Question, MessageBoxResult.Cancel);

                        if (result == MessageBoxResult.OK)
                        {
                            SelectedNumbers.Clear();
                            LoadNumbers();
                        }
                    }
                    else LoadNumbers();
                }));
            }
        }

        private RelayCommand loadExcelCommand;


        /// <summary>
        /// 查看预留号码
        /// </summary>
        public RelayCommand LoadExcelCommand
        {
            get
            {
                return loadExcelCommand ?? (loadExcelCommand = new RelayCommand(() =>
                {
                    var base_dir = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
                    var excelfile = base_dir + "\\Data\\numbers.xlsx";

                    if (System.IO.File.Exists(excelfile))
                        System.Diagnostics.Process.Start(excelfile);
                }));
            }
        }

        private RelayCommand resetCommand;

        /// <summary>
        /// 清除数据库中的数据，重新从Excel加载，一般情况下只有开发人员测试使用
        /// </summary>
        public RelayCommand ResetDataCommand
        {
            get
            {
                return resetCommand ?? (resetCommand = new RelayCommand(() =>
                {

                    if (MessageBox.Show("此操作将清除数据库数据，重新从Excel文件导入数据，\r\n\r\n之前的销售和预留号码等信息将一并清除，确认进行此项操作吗？", "警告", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.Yes)
                    {
                        AppService.ClearTable();
                        LoadNumbers();
                    }
                }));
            }
        }
    }
}